chosen.jquery.js ➔ ctor   A
last analyzed

Complexity

Conditions 5

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 1
rs 9.3333
c 0
b 0
f 0
cc 5
1
/*!
2
 Chosen, a Select Box Enhancer for jQuery and Prototype
3
 by Patrick Filler for Harvest, http://getharvest.com
4
5
 Version 1.1.0
6
 Full source at https://github.com/harvesthq/chosen
7
 Copyright (c) 2011 Harvest http://getharvest.com
8
9
 MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
 This file is generated by `grunt build`, do not edit it by hand.
11
 */
12
13
(function() {
14
    var $, AbstractChosen, Chosen, SelectParser, _ref,
15
        __hasProp = {}.hasOwnProperty,
16
        __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like ctor should be capitalized.
Loading history...
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
17
18
    SelectParser = (function() {
19
        function SelectParser() {
20
            this.options_index = 0;
21
            this.parsed = [];
22
        }
23
24
        SelectParser.prototype.add_node = function(child) {
25
            if (child.nodeName.toUpperCase() === "OPTGROUP") {
26
                return this.add_group(child);
27
            } else {
28
                return this.add_option(child);
29
            }
30
        };
31
32
        SelectParser.prototype.add_group = function(group) {
33
            var group_position, option, _i, _len, _ref, _results;
34
            group_position = this.parsed.length;
35
            this.parsed.push({
36
                array_index: group_position,
37
                group: true,
38
                label: this.escapeExpression(group.label),
39
                children: 0,
40
                disabled: group.disabled
41
            });
42
            _ref = group.childNodes;
43
            _results = [];
44
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
45
                option = _ref[_i];
46
                _results.push(this.add_option(option, group_position, group.disabled));
47
            }
48
            return _results;
49
        };
50
51
        SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
52
            if (option.nodeName.toUpperCase() === "OPTION") {
53
                if (option.text !== "") {
54
                    if (group_position != null) {
55
                        this.parsed[group_position].children += 1;
56
                    }
57
                    this.parsed.push({
58
                        array_index: this.parsed.length,
59
                        options_index: this.options_index,
60
                        value: option.value,
61
                        text: option.text,
62
                        html: option.innerHTML,
63
                        selected: option.selected,
64
                        disabled: group_disabled === true ? group_disabled : option.disabled,
65
                        group_array_index: group_position,
66
                        classes: option.className,
67
                        style: option.style.cssText
68
                    });
69
                } else {
70
                    this.parsed.push({
71
                        array_index: this.parsed.length,
72
                        options_index: this.options_index,
73
                        empty: true
74
                    });
75
                }
76
                return this.options_index += 1;
77
            }
78
        };
79
80
        SelectParser.prototype.escapeExpression = function(text) {
81
            var map, unsafe_chars;
82
            if ((text == null) || text === false) {
83
                return "";
84
            }
85
            if (!/[\&\<\>\"\'\`]/.test(text)) {
86
                return text;
87
            }
88
            map = {
89
                "<": "&lt;",
90
                ">": "&gt;",
91
                '"': "&quot;",
92
                "'": "&#x27;",
93
                "`": "&#x60;"
94
            };
95
            unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
96
            return text.replace(unsafe_chars, function(chr) {
97
                return map[chr] || "&amp;";
98
            });
99
        };
100
101
        return SelectParser;
102
103
    })();
104
105
    SelectParser.select_to_array = function(select) {
106
        var child, parser, _i, _len, _ref;
107
        parser = new SelectParser();
108
        _ref = select.childNodes;
109
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
110
            child = _ref[_i];
111
            parser.add_node(child);
112
        }
113
        return parser.parsed;
114
    };
115
116
    AbstractChosen = (function() {
117
        function AbstractChosen(form_field, options) {
118
            this.form_field = form_field;
119
            this.options = options != null ? options : {};
120
            if (!AbstractChosen.browser_is_supported()) {
121
                return;
122
            }
123
            this.is_multiple = this.form_field.multiple;
124
            this.set_default_text();
125
            this.set_default_values();
126
            this.setup();
127
            this.set_up_html();
128
            this.register_observers();
129
        }
130
131
        AbstractChosen.prototype.set_default_values = function() {
132
            var _this = this;
133
            this.click_test_action = function(evt) {
134
                return _this.test_active_click(evt);
135
            };
136
            this.activate_action = function(evt) {
137
                return _this.activate_field(evt);
138
            };
139
            this.active_field = false;
140
            this.mouse_on_container = false;
141
            this.results_showing = false;
142
            this.result_highlighted = null;
143
            this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
144
            this.disable_search_threshold = this.options.disable_search_threshold || 0;
145
            this.disable_search = this.options.disable_search || false;
146
            this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
147
            this.group_search = this.options.group_search != null ? this.options.group_search : true;
148
            this.search_contains = this.options.search_contains || false;
149
            this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
150
            this.max_selected_options = this.options.max_selected_options || Infinity;
151
            this.inherit_select_classes = this.options.inherit_select_classes || false;
152
            this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
153
            return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
154
        };
155
156
        AbstractChosen.prototype.set_default_text = function() {
157
            if (this.form_field.getAttribute("data-placeholder")) {
158
                this.default_text = this.form_field.getAttribute("data-placeholder");
159
            } else if (this.is_multiple) {
160
                this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
161
            } else {
162
                this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
163
            }
164
            return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
165
        };
166
167
        AbstractChosen.prototype.mouse_enter = function() {
168
            return this.mouse_on_container = true;
169
        };
170
171
        AbstractChosen.prototype.mouse_leave = function() {
172
            return this.mouse_on_container = false;
173
        };
174
175
        AbstractChosen.prototype.input_focus = function(evt) {
176
            var _this = this;
177
            if (this.is_multiple) {
178
                if (!this.active_field) {
179
                    return setTimeout((function() {
180
                        return _this.container_mousedown();
181
                    }), 50);
182
                }
183
            } else {
184
                if (!this.active_field) {
185
                    return this.activate_field();
186
                }
187
            }
188
        };
189
190
        AbstractChosen.prototype.input_blur = function(evt) {
191
            var _this = this;
192
            if (!this.mouse_on_container) {
193
                this.active_field = false;
194
                return setTimeout((function() {
195
                    return _this.blur_test();
196
                }), 100);
197
            }
198
        };
199
200
        AbstractChosen.prototype.results_option_build = function(options) {
201
            var content, data, _i, _len, _ref;
202
            content = '';
203
            _ref = this.results_data;
204
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
205
                data = _ref[_i];
206
                if (data.group) {
207
                    content += this.result_add_group(data);
208
                } else {
209
                    content += this.result_add_option(data);
210
                }
211
                if (options != null ? options.first : void 0) {
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
212
                    if (data.selected && this.is_multiple) {
213
                        this.choice_build(data);
214
                    } else if (data.selected && !this.is_multiple) {
215
                        this.single_set_selected_text(data.text);
216
                    }
217
                }
218
            }
219
            return content;
220
        };
221
222
        AbstractChosen.prototype.result_add_option = function(option) {
223
            var classes, option_el;
224
            if (!option.search_match) {
225
                return '';
226
            }
227
            if (!this.include_option_in_results(option)) {
228
                return '';
229
            }
230
            classes = [];
231
            if (!option.disabled && !(option.selected && this.is_multiple)) {
232
                classes.push("active-result");
233
            }
234
            if (option.disabled && !(option.selected && this.is_multiple)) {
235
                classes.push("disabled-result");
236
            }
237
            if (option.selected) {
238
                classes.push("result-selected");
239
            }
240
            if (option.group_array_index != null) {
241
                classes.push("group-option");
242
            }
243
            if (option.classes !== "") {
244
                classes.push(option.classes);
245
            }
246
            option_el = document.createElement("li");
247
            option_el.className = classes.join(" ");
248
            option_el.style.cssText = option.style;
249
            option_el.setAttribute("data-option-array-index", option.array_index);
250
            option_el.innerHTML = option.search_text;
251
            return this.outerHTML(option_el);
252
        };
253
254
        AbstractChosen.prototype.result_add_group = function(group) {
255
            var group_el;
256
            if (!(group.search_match || group.group_match)) {
257
                return '';
258
            }
259
            if (!(group.active_options > 0)) {
260
                return '';
261
            }
262
            group_el = document.createElement("li");
263
            group_el.className = "group-result";
264
            group_el.innerHTML = group.search_text;
265
            return this.outerHTML(group_el);
266
        };
267
268
        AbstractChosen.prototype.results_update_field = function() {
269
            this.set_default_text();
270
            if (!this.is_multiple) {
271
                this.results_reset_cleanup();
272
            }
273
            this.result_clear_highlight();
274
            this.results_build();
275
            if (this.results_showing) {
276
                return this.winnow_results();
277
            }
278
        };
279
280
        AbstractChosen.prototype.reset_single_select_options = function() {
281
            var result, _i, _len, _ref, _results;
282
            _ref = this.results_data;
283
            _results = [];
284
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
285
                result = _ref[_i];
286
                if (result.selected) {
287
                    _results.push(result.selected = false);
288
                } else {
289
                    _results.push(void 0);
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
290
                }
291
            }
292
            return _results;
293
        };
294
295
        AbstractChosen.prototype.results_toggle = function() {
296
            if (this.results_showing) {
297
                return this.results_hide();
298
            } else {
299
                return this.results_show();
300
            }
301
        };
302
303
        AbstractChosen.prototype.results_search = function(evt) {
304
            if (this.results_showing) {
305
                return this.winnow_results();
306
            } else {
307
                return this.results_show();
308
            }
309
        };
310
311
        AbstractChosen.prototype.winnow_results = function() {
312
            var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
313
            this.no_results_clear();
314
            results = 0;
315
            searchText = this.get_search_text();
316
            escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
317
            regexAnchor = this.search_contains ? "" : "^";
318
            regex = new RegExp(regexAnchor + escapedSearchText, 'i');
319
            zregex = new RegExp(escapedSearchText, 'i');
320
            _ref = this.results_data;
321
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
322
                option = _ref[_i];
323
                option.search_match = false;
324
                results_group = null;
325
                if (this.include_option_in_results(option)) {
326
                    if (option.group) {
327
                        option.group_match = false;
328
                        option.active_options = 0;
329
                    }
330
                    if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
331
                        results_group = this.results_data[option.group_array_index];
332
                        if (results_group.active_options === 0 && results_group.search_match) {
333
                            results += 1;
334
                        }
335
                        results_group.active_options += 1;
336
                    }
337
                    if (!(option.group && !this.group_search)) {
338
                        option.search_text = option.group ? option.label : option.html;
339
                        option.search_match = this.search_string_match(option.search_text, regex);
340
                        if (option.search_match && !option.group) {
341
                            results += 1;
342
                        }
343
                        if (option.search_match) {
344
                            if (searchText.length) {
345
                                startpos = option.search_text.search(zregex);
346
                                text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
347
                                option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
348
                            }
349
                            if (results_group != null) {
350
                                results_group.group_match = true;
351
                            }
352
                        } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
353
                            option.search_match = true;
354
                        }
355
                    }
356
                }
357
            }
358
            this.result_clear_highlight();
359
            if (results < 1 && searchText.length) {
360
                this.update_results_content("");
361
                return this.no_results(searchText);
362
            } else {
363
                this.update_results_content(this.results_option_build());
364
                return this.winnow_results_set_highlight();
365
            }
366
        };
367
368
        AbstractChosen.prototype.search_string_match = function(search_string, regex) {
369
            var part, parts, _i, _len;
370
            if (regex.test(search_string)) {
371
                return true;
372
            } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
373
                parts = search_string.replace(/\[|\]/g, "").split(" ");
374
                if (parts.length) {
375
                    for (_i = 0, _len = parts.length; _i < _len; _i++) {
376
                        part = parts[_i];
377
                        if (regex.test(part)) {
378
                            return true;
379
                        }
380
                    }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
381
                }
382
            }
383
        };
384
385
        AbstractChosen.prototype.choices_count = function() {
386
            var option, _i, _len, _ref;
387
            if (this.selected_option_count != null) {
388
                return this.selected_option_count;
389
            }
390
            this.selected_option_count = 0;
391
            _ref = this.form_field.options;
392
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
393
                option = _ref[_i];
394
                if (option.selected) {
395
                    this.selected_option_count += 1;
396
                }
397
            }
398
            return this.selected_option_count;
399
        };
400
401
        AbstractChosen.prototype.choices_click = function(evt) {
402
            evt.preventDefault();
403
            if (!(this.results_showing || this.is_disabled)) {
404
                return this.results_show();
405
            }
406
        };
407
408
        AbstractChosen.prototype.keyup_checker = function(evt) {
409
            var stroke, _ref;
410
            stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
411
            this.search_field_scale();
412
            switch (stroke) {
413
                case 8:
414
                    if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
415
                        return this.keydown_backstroke();
416
                    } else if (!this.pending_backstroke) {
417
                        this.result_clear_highlight();
418
                        return this.results_search();
419
                    }
420
                    break;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
421
                case 13:
422
                    evt.preventDefault();
423
                    if (this.results_showing) {
424
                        return this.result_select(evt);
425
                    }
426
                    break;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
427
                case 27:
428
                    if (this.results_showing) {
429
                        this.results_hide();
430
                    }
431
                    return true;
432
                case 9:
433
                case 38:
434
                case 40:
435
                case 16:
436
                case 91:
437
                case 17:
438
                    break;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
439
                default:
440
                    return this.results_search();
441
            }
442
        };
443
444
        AbstractChosen.prototype.clipboard_event_checker = function(evt) {
445
            var _this = this;
446
            return setTimeout((function() {
447
                return _this.results_search();
448
            }), 50);
449
        };
450
451
        AbstractChosen.prototype.container_width = function() {
452
            if (this.options.width != null) {
453
                return this.options.width;
454
            } else {
455
                return "" + this.form_field.offsetWidth + "px";
456
            }
457
        };
458
459
        AbstractChosen.prototype.include_option_in_results = function(option) {
460
            if (this.is_multiple && (!this.display_selected_options && option.selected)) {
461
                return false;
462
            }
463
            if (!this.display_disabled_options && option.disabled) {
464
                return false;
465
            }
466
            if (option.empty) {
467
                return false;
468
            }
469
            return true;
470
        };
471
472
        AbstractChosen.prototype.search_results_touchstart = function(evt) {
473
            this.touch_started = true;
474
            return this.search_results_mouseover(evt);
475
        };
476
477
        AbstractChosen.prototype.search_results_touchmove = function(evt) {
478
            this.touch_started = false;
479
            return this.search_results_mouseout(evt);
480
        };
481
482
        AbstractChosen.prototype.search_results_touchend = function(evt) {
483
            if (this.touch_started) {
484
                return this.search_results_mouseup(evt);
485
            }
486
        };
487
488
        AbstractChosen.prototype.outerHTML = function(element) {
489
            var tmp;
490
            if (element.outerHTML) {
491
                return element.outerHTML;
492
            }
493
            tmp = document.createElement("div");
494
            tmp.appendChild(element);
495
            return tmp.innerHTML;
496
        };
497
498
        AbstractChosen.browser_is_supported = function() {
499
            if (window.navigator.appName === "Microsoft Internet Explorer") {
500
                return document.documentMode >= 8;
501
            }
502
            if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
503
                return false;
504
            }
505
            if (/Android/i.test(window.navigator.userAgent)) {
506
                if (/Mobile/i.test(window.navigator.userAgent)) {
507
                    return false;
508
                }
509
            }
510
            return true;
511
        };
512
513
        AbstractChosen.default_multiple_text = "Select Some Options";
514
515
        AbstractChosen.default_single_text = "Select an Option";
516
517
        AbstractChosen.default_no_result_text = "No results match";
518
519
        return AbstractChosen;
520
521
    })();
522
523
    $ = jQuery;
524
525
    $.fn.extend({
526
        chosen: function(options) {
527
            if (!AbstractChosen.browser_is_supported()) {
528
                return this;
529
            }
530
            return this.each(function(input_field) {
531
                var $this, chosen;
532
                $this = $(this);
533
                chosen = $this.data('chosen');
534
                if (options === 'destroy' && chosen) {
535
                    chosen.destroy();
536
                } else if (!chosen) {
537
                    $this.data('chosen', new Chosen(this, options));
538
                }
539
            });
540
        }
541
    });
542
543
    Chosen = (function(_super) {
544
        __extends(Chosen, _super);
545
546
        function Chosen() {
547
            _ref = Chosen.__super__.constructor.apply(this, arguments);
548
            return _ref;
549
        }
550
551
        Chosen.prototype.setup = function() {
552
            this.form_field_jq = $(this.form_field);
553
            this.current_selectedIndex = this.form_field.selectedIndex;
554
            return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
555
        };
556
557
        Chosen.prototype.set_up_html = function() {
558
            var container_classes, container_props;
559
            container_classes = ["chosen-container"];
560
            container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
561
            if (this.inherit_select_classes && this.form_field.className) {
562
                container_classes.push(this.form_field.className);
563
            }
564
            if (this.is_rtl) {
565
                container_classes.push("chosen-rtl");
566
            }
567
            container_props = {
568
                'class': container_classes.join(' '),
569
                'style': "width: " + (this.container_width()) + ";",
570
                'title': this.form_field.title
571
            };
572
            if (this.form_field.id.length) {
573
                container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
574
            }
575
            this.container = $("<div />", container_props);
576
            if (this.is_multiple) {
577
                this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
578
            } else {
579
                this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
580
            }
581
            this.form_field_jq.hide().after(this.container);
582
            this.dropdown = this.container.find('div.chosen-drop').first();
583
            this.search_field = this.container.find('input').first();
584
            this.search_results = this.container.find('ul.chosen-results').first();
585
            this.search_field_scale();
586
            this.search_no_results = this.container.find('li.no-results').first();
587
            if (this.is_multiple) {
588
                this.search_choices = this.container.find('ul.chosen-choices').first();
589
                this.search_container = this.container.find('li.search-field').first();
590
            } else {
591
                this.search_container = this.container.find('div.chosen-search').first();
592
                this.selected_item = this.container.find('.chosen-single').first();
593
            }
594
            this.results_build();
595
            this.set_tab_index();
596
            this.set_label_behavior();
597
            return this.form_field_jq.trigger("chosen:ready", {
598
                chosen: this
599
            });
600
        };
601
602
        Chosen.prototype.register_observers = function() {
603
            var _this = this;
604
            this.container.bind('mousedown.chosen', function(evt) {
605
                _this.container_mousedown(evt);
606
            });
607
            this.container.bind('mouseup.chosen', function(evt) {
608
                _this.container_mouseup(evt);
609
            });
610
            this.container.bind('mouseenter.chosen', function(evt) {
611
                _this.mouse_enter(evt);
612
            });
613
            this.container.bind('mouseleave.chosen', function(evt) {
614
                _this.mouse_leave(evt);
615
            });
616
            this.search_results.bind('mouseup.chosen', function(evt) {
617
                _this.search_results_mouseup(evt);
618
            });
619
            this.search_results.bind('mouseover.chosen', function(evt) {
620
                _this.search_results_mouseover(evt);
621
            });
622
            this.search_results.bind('mouseout.chosen', function(evt) {
623
                _this.search_results_mouseout(evt);
624
            });
625
            this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
626
                _this.search_results_mousewheel(evt);
627
            });
628
            this.search_results.bind('touchstart.chosen', function(evt) {
629
                _this.search_results_touchstart(evt);
630
            });
631
            this.search_results.bind('touchmove.chosen', function(evt) {
632
                _this.search_results_touchmove(evt);
633
            });
634
            this.search_results.bind('touchend.chosen', function(evt) {
635
                _this.search_results_touchend(evt);
636
            });
637
            this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
638
                _this.results_update_field(evt);
639
            });
640
            this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
641
                _this.activate_field(evt);
642
            });
643
            this.form_field_jq.bind("chosen:open.chosen", function(evt) {
644
                _this.container_mousedown(evt);
645
            });
646
            this.form_field_jq.bind("chosen:close.chosen", function(evt) {
647
                _this.input_blur(evt);
648
            });
649
            this.search_field.bind('blur.chosen', function(evt) {
650
                _this.input_blur(evt);
651
            });
652
            this.search_field.bind('keyup.chosen', function(evt) {
653
                _this.keyup_checker(evt);
654
            });
655
            this.search_field.bind('keydown.chosen', function(evt) {
656
                _this.keydown_checker(evt);
657
            });
658
            this.search_field.bind('focus.chosen', function(evt) {
659
                _this.input_focus(evt);
660
            });
661
            this.search_field.bind('cut.chosen', function(evt) {
662
                _this.clipboard_event_checker(evt);
663
            });
664
            this.search_field.bind('paste.chosen', function(evt) {
665
                _this.clipboard_event_checker(evt);
666
            });
667
            if (this.is_multiple) {
668
                return this.search_choices.bind('click.chosen', function(evt) {
669
                    _this.choices_click(evt);
670
                });
671
            } else {
672
                return this.container.bind('click.chosen', function(evt) {
673
                    evt.preventDefault();
674
                });
675
            }
676
        };
677
678
        Chosen.prototype.destroy = function() {
679
            $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
680
            if (this.search_field[0].tabIndex) {
681
                this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
682
            }
683
            this.container.remove();
684
            this.form_field_jq.removeData('chosen');
685
            return this.form_field_jq.show();
686
        };
687
688
        Chosen.prototype.search_field_disabled = function() {
689
            this.is_disabled = this.form_field_jq[0].disabled;
690
            if (this.is_disabled) {
691
                this.container.addClass('chosen-disabled');
692
                this.search_field[0].disabled = true;
693
                if (!this.is_multiple) {
694
                    this.selected_item.unbind("focus.chosen", this.activate_action);
695
                }
696
                return this.close_field();
697
            } else {
698
                this.container.removeClass('chosen-disabled');
699
                this.search_field[0].disabled = false;
700
                if (!this.is_multiple) {
701
                    return this.selected_item.bind("focus.chosen", this.activate_action);
702
                }
703
            }
704
        };
705
706
        Chosen.prototype.container_mousedown = function(evt) {
707
            if (!this.is_disabled) {
708
                if (evt && evt.type === "mousedown" && !this.results_showing) {
709
                    evt.preventDefault();
710
                }
711
                if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
712
                    if (!this.active_field) {
713
                        if (this.is_multiple) {
714
                            this.search_field.val("");
715
                        }
716
                        $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
717
                        this.results_show();
718
                    } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
719
                        evt.preventDefault();
720
                        this.results_toggle();
721
                    }
722
                    return this.activate_field();
723
                }
724
            }
725
        };
726
727
        Chosen.prototype.container_mouseup = function(evt) {
728
            if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
729
                return this.results_reset(evt);
730
            }
731
        };
732
733
        Chosen.prototype.search_results_mousewheel = function(evt) {
734
            var delta;
735
            if (evt.originalEvent) {
736
                delta = -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
737
            }
738
            if (delta != null) {
0 ignored issues
show
Bug introduced by
The variable delta does not seem to be initialized in case evt.originalEvent on line 735 is false. Are you sure this can never be the case?
Loading history...
739
                evt.preventDefault();
740
                if (evt.type === 'DOMMouseScroll') {
741
                    delta = delta * 40;
742
                }
743
                return this.search_results.scrollTop(delta + this.search_results.scrollTop());
744
            }
745
        };
746
747
        Chosen.prototype.blur_test = function(evt) {
748
            if (!this.active_field && this.container.hasClass("chosen-container-active")) {
749
                return this.close_field();
750
            }
751
        };
752
753
        Chosen.prototype.close_field = function() {
754
            $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
755
            this.active_field = false;
756
            this.results_hide();
757
            this.container.removeClass("chosen-container-active");
758
            this.clear_backstroke();
759
            this.show_search_field_default();
760
            return this.search_field_scale();
761
        };
762
763
        Chosen.prototype.activate_field = function() {
764
            this.container.addClass("chosen-container-active");
765
            this.active_field = true;
766
            this.search_field.val(this.search_field.val());
767
            return this.search_field.focus();
768
        };
769
770
        Chosen.prototype.test_active_click = function(evt) {
771
            var active_container;
772
            active_container = $(evt.target).closest('.chosen-container');
773
            if (active_container.length && this.container[0] === active_container[0]) {
774
                return this.active_field = true;
775
            } else {
776
                return this.close_field();
777
            }
778
        };
779
780
        Chosen.prototype.results_build = function() {
781
            this.parsing = true;
782
            this.selected_option_count = null;
783
            this.results_data = SelectParser.select_to_array(this.form_field);
784
            if (this.is_multiple) {
785
                this.search_choices.find("li.search-choice").remove();
786
            } else if (!this.is_multiple) {
787
                this.single_set_selected_text();
788
                if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
789
                    this.search_field[0].readOnly = true;
790
                    this.container.addClass("chosen-container-single-nosearch");
791
                } else {
792
                    this.search_field[0].readOnly = false;
793
                    this.container.removeClass("chosen-container-single-nosearch");
794
                }
795
            }
796
            this.update_results_content(this.results_option_build({
797
                first: true
798
            }));
799
            this.search_field_disabled();
800
            this.show_search_field_default();
801
            this.search_field_scale();
802
            return this.parsing = false;
803
        };
804
805
        Chosen.prototype.result_do_highlight = function(el) {
806
            var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
807
            if (el.length) {
808
                this.result_clear_highlight();
809
                this.result_highlight = el;
810
                this.result_highlight.addClass("highlighted");
811
                maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
812
                visible_top = this.search_results.scrollTop();
813
                visible_bottom = maxHeight + visible_top;
814
                high_top = this.result_highlight.position().top + this.search_results.scrollTop();
815
                high_bottom = high_top + this.result_highlight.outerHeight();
816
                if (high_bottom >= visible_bottom) {
817
                    return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
818
                } else if (high_top < visible_top) {
819
                    return this.search_results.scrollTop(high_top);
820
                }
821
            }
822
        };
823
824
        Chosen.prototype.result_clear_highlight = function() {
825
            if (this.result_highlight) {
826
                this.result_highlight.removeClass("highlighted");
827
            }
828
            return this.result_highlight = null;
829
        };
830
831
        Chosen.prototype.results_show = function() {
832
            if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
833
                this.form_field_jq.trigger("chosen:maxselected", {
834
                    chosen: this
835
                });
836
                return false;
837
            }
838
            this.container.addClass("chosen-with-drop");
839
            this.results_showing = true;
840
            this.search_field.focus();
841
            this.search_field.val(this.search_field.val());
842
            this.winnow_results();
843
            return this.form_field_jq.trigger("chosen:showing_dropdown", {
844
                chosen: this
845
            });
846
        };
847
848
        Chosen.prototype.update_results_content = function(content) {
849
            return this.search_results.html(content);
850
        };
851
852
        Chosen.prototype.results_hide = function() {
853
            if (this.results_showing) {
854
                this.result_clear_highlight();
855
                this.container.removeClass("chosen-with-drop");
856
                this.form_field_jq.trigger("chosen:hiding_dropdown", {
857
                    chosen: this
858
                });
859
            }
860
            return this.results_showing = false;
861
        };
862
863
        Chosen.prototype.set_tab_index = function(el) {
864
            var ti;
865
            if (this.form_field.tabIndex) {
866
                ti = this.form_field.tabIndex;
867
                this.form_field.tabIndex = -1;
868
                return this.search_field[0].tabIndex = ti;
869
            }
870
        };
871
872
        Chosen.prototype.set_label_behavior = function() {
873
            var _this = this;
874
            this.form_field_label = this.form_field_jq.parents("label");
875
            if (!this.form_field_label.length && this.form_field.id.length) {
876
                this.form_field_label = $("label[for='" + this.form_field.id + "']");
877
            }
878
            if (this.form_field_label.length > 0) {
879
                return this.form_field_label.bind('click.chosen', function(evt) {
880
                    if (_this.is_multiple) {
881
                        return _this.container_mousedown(evt);
882
                    } else {
883
                        return _this.activate_field();
884
                    }
885
                });
886
            }
887
        };
888
889
        Chosen.prototype.show_search_field_default = function() {
890
            if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
891
                this.search_field.val(this.default_text);
892
                return this.search_field.addClass("default");
893
            } else {
894
                this.search_field.val("");
895
                return this.search_field.removeClass("default");
896
            }
897
        };
898
899
        Chosen.prototype.search_results_mouseup = function(evt) {
900
            var target;
901
            target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
902
            if (target.length) {
903
                this.result_highlight = target;
904
                this.result_select(evt);
905
                return this.search_field.focus();
906
            }
907
        };
908
909
        Chosen.prototype.search_results_mouseover = function(evt) {
910
            var target;
911
            target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
912
            if (target) {
913
                return this.result_do_highlight(target);
914
            }
915
        };
916
917
        Chosen.prototype.search_results_mouseout = function(evt) {
918
            if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
919
                return this.result_clear_highlight();
920
            }
921
        };
922
923
        Chosen.prototype.choice_build = function(item) {
924
            var choice, close_link,
925
                _this = this;
926
            choice = $('<li />', {
927
                "class": "search-choice"
928
            }).html("<span>" + item.html + "</span>");
929
            if (item.disabled) {
930
                choice.addClass('search-choice-disabled');
931
            } else {
932
                close_link = $('<a />', {
933
                    "class": 'search-choice-close',
934
                    'data-option-array-index': item.array_index
935
                });
936
                close_link.bind('click.chosen', function(evt) {
937
                    return _this.choice_destroy_link_click(evt);
938
                });
939
                choice.append(close_link);
940
            }
941
            return this.search_container.before(choice);
942
        };
943
944
        Chosen.prototype.choice_destroy_link_click = function(evt) {
945
            evt.preventDefault();
946
            evt.stopPropagation();
947
            if (!this.is_disabled) {
948
                return this.choice_destroy($(evt.target));
949
            }
950
        };
951
952
        Chosen.prototype.choice_destroy = function(link) {
953
            if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
954
                this.show_search_field_default();
955
                if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
956
                    this.results_hide();
957
                }
958
                link.parents('li').first().remove();
959
                return this.search_field_scale();
960
            }
961
        };
962
963
        Chosen.prototype.results_reset = function() {
964
            this.reset_single_select_options();
965
            this.form_field.options[0].selected = true;
966
            this.single_set_selected_text();
967
            this.show_search_field_default();
968
            this.results_reset_cleanup();
969
            this.form_field_jq.trigger("change");
970
            if (this.active_field) {
971
                return this.results_hide();
972
            }
973
        };
974
975
        Chosen.prototype.results_reset_cleanup = function() {
976
            this.current_selectedIndex = this.form_field.selectedIndex;
977
            return this.selected_item.find("abbr").remove();
978
        };
979
980
        Chosen.prototype.result_select = function(evt) {
981
            var high, item;
982
            if (this.result_highlight) {
983
                high = this.result_highlight;
984
                this.result_clear_highlight();
985
                if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
986
                    this.form_field_jq.trigger("chosen:maxselected", {
987
                        chosen: this
988
                    });
989
                    return false;
990
                }
991
                if (this.is_multiple) {
992
                    high.removeClass("active-result");
993
                } else {
994
                    this.reset_single_select_options();
995
                }
996
                item = this.results_data[high[0].getAttribute("data-option-array-index")];
997
                item.selected = true;
998
                this.form_field.options[item.options_index].selected = true;
999
                this.selected_option_count = null;
1000
                if (this.is_multiple) {
1001
                    this.choice_build(item);
1002
                } else {
1003
                    this.single_set_selected_text(item.text);
1004
                }
1005
                if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1006
                    this.results_hide();
1007
                }
1008
                this.search_field.val("");
1009
                if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1010
                    this.form_field_jq.trigger("change", {
1011
                        'selected': this.form_field.options[item.options_index].value
1012
                    });
1013
                }
1014
                this.current_selectedIndex = this.form_field.selectedIndex;
1015
                return this.search_field_scale();
1016
            }
1017
        };
1018
1019
        Chosen.prototype.single_set_selected_text = function(text) {
1020
            if (text == null) {
1021
                text = this.default_text;
1022
            }
1023
            if (text === this.default_text) {
1024
                this.selected_item.addClass("chosen-default");
1025
            } else {
1026
                this.single_deselect_control_build();
1027
                this.selected_item.removeClass("chosen-default");
1028
            }
1029
            return this.selected_item.find("span").text(text);
1030
        };
1031
1032
        Chosen.prototype.result_deselect = function(pos) {
1033
            var result_data;
1034
            result_data = this.results_data[pos];
1035
            if (!this.form_field.options[result_data.options_index].disabled) {
1036
                result_data.selected = false;
1037
                this.form_field.options[result_data.options_index].selected = false;
1038
                this.selected_option_count = null;
1039
                this.result_clear_highlight();
1040
                if (this.results_showing) {
1041
                    this.winnow_results();
1042
                }
1043
                this.form_field_jq.trigger("change", {
1044
                    deselected: this.form_field.options[result_data.options_index].value
1045
                });
1046
                this.search_field_scale();
1047
                return true;
1048
            } else {
1049
                return false;
1050
            }
1051
        };
1052
1053
        Chosen.prototype.single_deselect_control_build = function() {
1054
            if (!this.allow_single_deselect) {
1055
                return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
1056
            }
1057
            if (!this.selected_item.find("abbr").length) {
1058
                this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1059
            }
1060
            return this.selected_item.addClass("chosen-single-with-deselect");
1061
        };
1062
1063
        Chosen.prototype.get_search_text = function() {
1064
            if (this.search_field.val() === this.default_text) {
1065
                return "";
1066
            } else {
1067
                return $('<div/>').text($.trim(this.search_field.val())).html();
1068
            }
1069
        };
1070
1071
        Chosen.prototype.winnow_results_set_highlight = function() {
1072
            var do_high, selected_results;
1073
            selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1074
            do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1075
            if (do_high != null) {
1076
                return this.result_do_highlight(do_high);
1077
            }
1078
        };
1079
1080
        Chosen.prototype.no_results = function(terms) {
1081
            var no_results_html;
1082
            no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1083
            no_results_html.find("span").first().html(terms);
1084
            this.search_results.append(no_results_html);
1085
            return this.form_field_jq.trigger("chosen:no_results", {
1086
                chosen: this
1087
            });
1088
        };
1089
1090
        Chosen.prototype.no_results_clear = function() {
1091
            return this.search_results.find(".no-results").remove();
1092
        };
1093
1094
        Chosen.prototype.keydown_arrow = function() {
1095
            var next_sib;
1096
            if (this.results_showing && this.result_highlight) {
1097
                next_sib = this.result_highlight.nextAll("li.active-result").first();
1098
                if (next_sib) {
1099
                    return this.result_do_highlight(next_sib);
1100
                }
1101
            } else {
1102
                return this.results_show();
1103
            }
1104
        };
1105
1106
        Chosen.prototype.keyup_arrow = function() {
1107
            var prev_sibs;
1108
            if (!this.results_showing && !this.is_multiple) {
1109
                return this.results_show();
1110
            } else if (this.result_highlight) {
1111
                prev_sibs = this.result_highlight.prevAll("li.active-result");
1112
                if (prev_sibs.length) {
1113
                    return this.result_do_highlight(prev_sibs.first());
1114
                } else {
1115
                    if (this.choices_count() > 0) {
1116
                        this.results_hide();
1117
                    }
1118
                    return this.result_clear_highlight();
1119
                }
1120
            }
1121
        };
1122
1123
        Chosen.prototype.keydown_backstroke = function() {
1124
            var next_available_destroy;
1125
            if (this.pending_backstroke) {
1126
                this.choice_destroy(this.pending_backstroke.find("a").first());
1127
                return this.clear_backstroke();
1128
            } else {
1129
                next_available_destroy = this.search_container.siblings("li.search-choice").last();
1130
                if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1131
                    this.pending_backstroke = next_available_destroy;
1132
                    if (this.single_backstroke_delete) {
1133
                        return this.keydown_backstroke();
1134
                    } else {
1135
                        return this.pending_backstroke.addClass("search-choice-focus");
1136
                    }
1137
                }
1138
            }
1139
        };
1140
1141
        Chosen.prototype.clear_backstroke = function() {
1142
            if (this.pending_backstroke) {
1143
                this.pending_backstroke.removeClass("search-choice-focus");
1144
            }
1145
            return this.pending_backstroke = null;
1146
        };
1147
1148
        Chosen.prototype.keydown_checker = function(evt) {
1149
            var stroke, _ref1;
1150
            stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1151
            this.search_field_scale();
1152
            if (stroke !== 8 && this.pending_backstroke) {
1153
                this.clear_backstroke();
1154
            }
1155
            switch (stroke) {
1156
                case 8:
1157
                    this.backstroke_length = this.search_field.val().length;
1158
                    break;
1159
                case 9:
1160
                    if (this.results_showing && !this.is_multiple) {
1161
                        this.result_select(evt);
1162
                    }
1163
                    this.mouse_on_container = false;
1164
                    break;
1165
                case 13:
1166
                    evt.preventDefault();
1167
                    break;
1168
                case 38:
1169
                    evt.preventDefault();
1170
                    this.keyup_arrow();
1171
                    break;
1172
                case 40:
1173
                    evt.preventDefault();
1174
                    this.keydown_arrow();
1175
                    break;
1176
            }
1177
        };
1178
1179
        Chosen.prototype.search_field_scale = function() {
1180
            var div, f_width, h, style, style_block, styles, w, _i, _len;
1181
            if (this.is_multiple) {
1182
                h = 0;
0 ignored issues
show
Unused Code introduced by
The variable h seems to be never used. Consider removing it.
Loading history...
1183
                w = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to variable w seems to be never used. Consider removing it.
Loading history...
1184
                style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1185
                styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1186
                for (_i = 0, _len = styles.length; _i < _len; _i++) {
1187
                    style = styles[_i];
1188
                    style_block += style + ":" + this.search_field.css(style) + ";";
1189
                }
1190
                div = $('<div />', {
1191
                    'style': style_block
1192
                });
1193
                div.text(this.search_field.val());
1194
                $('body').append(div);
1195
                w = div.width() + 25;
1196
                div.remove();
1197
                f_width = this.container.outerWidth();
1198
                if (w > f_width - 10) {
1199
                    w = f_width - 10;
1200
                }
1201
                return this.search_field.css({
1202
                    'width': w + 'px'
1203
                });
1204
            }
1205
        };
1206
1207
        return Chosen;
1208
1209
    })(AbstractChosen);
1210
1211
}).call(this);
1212